#ifndef XGE_UNITTEST_XPRIORITY_QUEUE_H_
#define XGE_UNITTEST_XPRIORITY_QUEUE_H_
#include "xge_common_config.h"
#include "xcommon_task.h"
#include "xworker_double_queue.h"
#include "xunit_test.h"
#include "xthread.h"
#include "xthread_delegate.h"
#include "xthread_manager.h"
#include "xassert.h"
#include "xsync.h"
#include "xtimer.h"
#include "xtask_memory_helper.h"
#include <stdio.h>


using xge::CommonTask;
using xge::xge_internal::WorkerQueue;
using xge::xge_internal::WorkerDoubleQueue;
using xge::xge_internal::ThreadHandler;
using xge::xge_internal::ThreadHandlerPtr;
using xge::xge_internal::ThreadDelegate;
using xge::xge_internal::ThreadDelegatePtr;
using xge::xge_internal::ThreadManager;
using xge::String;
using xge::xge_internal::Timer;
using xge::xge_internal::TaskPtr;
using xge::xge_internal::TaskMemoryHelper;


namespace {
  class MyCommonTask : public CommonTask {
  public:

    virtual void Execute() {
      for( size_t i = 0 ; i < 20 ; ++i )
        printf("MyCommonTask Executing.\n");
    }

    MyCommonTask() : CommonTask( REMOTE_BINDING ) {}
  };

  class MyDoubleQueueStub : public ThreadDelegate {
  public:
    virtual void ThreadMain() {
      queue_.Loop();
    }

    WorkerDoubleQueue queue_;
    ThreadHandlerPtr thread_handler_;
    ThreadDelegatePtr delegate_;

    MyDoubleQueueStub() : delegate_(this) {
      // doing the initialization
      thread_handler_ = ThreadManager::CreateXThread(
        NULL,
        delegate_,
        _xT("DoubleQueue"),
        "double_queue"
        );

      XASSERT(!thread_handler_.Null());
    }
  };
}

// Testing the common stuff
UNIT_TEST(DOUBLEQUEUETEST,Case1) {
  MyDoubleQueueStub* stub = new MyDoubleQueueStub();
  // doing the test here
  for( size_t i = 0 ; i < 10 ; ++i )
    stub->queue_.PushTask( TaskPtr( new MyCommonTask() ) ) ;
  // for the batching test goes here
  WorkerQueue::TaskPtrList task_list;
  size_t iCount=0;
  while(1) {
    // testing the batch operation
    task_list.clear();
    for( size_t i = 0 ; i < 10 ; ++i ) 
      task_list.push_back( TaskPtr( new MyCommonTask() ) );
    // push the list
    stub->queue_.PushTask(&task_list);
    // waiting till the end of the operation
    ++iCount;
    if( iCount > 20 ) {
      // stub operation using different style
#if 1
      stub->queue_.PostQuitWhenEmpty();
      stub->queue_.WaitWhenEmpty();
      stub->thread_handler_->Join();
      break;
      // ok
#else
      stub->queue_.PostQuitSoon();
      stub->queue_.WaitWhenRelease();
      stub->thread_handler_->Join();
      break;
#endif

    }

  }
  printf("Test over!\n");
  delete stub;

  ::getchar();
}



#endif 